from zope.interface import Interface, Attribute
from zope.publisher.interfaces.browser import IBrowserView

from plone.app.layout.navigation.interfaces import INavigationRoot

from Products.CMFPlone import PloneMessageFactory as _

from zope.schema import Choice, List, Tuple, Bool

from plone.app.relations.interfaces import IDCWorkflowRelationship, IAnnotationsContext
from zope.app.annotation.interfaces import IAnnotatable, IAttributeAnnotatable

from plone.app.controlpanel.language import ILanguageSelectionSchema
from z3c.relationfield.interfaces import IHasRelations

class AlreadyTranslated(Exception):
    """Raised when trying to create an existing translation."""
    pass

class CouldNotTranslate(Exception):
    """Raise when it can't finish a translation"""
    pass

class NotTranslatable(Exception):
    pass
    

#
# Configuration Interfaces
# 


class IPolicyOptions(Interface):
    """ Utility to manage the language related options
    """
    use_path_negotiation = Bool(
        title=_(u'label_language_codes_in_url',
                default=u"Use language codes in URL path for manual override."),
        default=True,
        required=False)

    use_cookie_negotiation = Bool(
        title=_(u'label_cookies_for_override',
                default=u"Use cookie for manual override."),
        default=True,
        required=False)

    use_cctld_negotiation = Bool(
        title=_(u'label_ccTLD_language',
                default=u"Use the virtual hostname of the Plone site."),
        default=False,
        required=False)

    use_request_negotiation = Bool(
        title=_(u'label_browser_language_negotiation',
                default=u"Use browser language request negotiation."),
        default=True,
        required=False)

    use_default_language = Bool(
        title=_(u'text_default_fallback',
                default=u"Default fallback (always enabled). This is the "
                         "language specified as default above."),
        default=True,
        required=False)

    force_language_urls = Bool(
        title=_(u'label_force_different_urls',
                default=u"Force different URLs for each language (redirect)."),
        default=True,
        required=False)

    start_neutral = Bool(
        title=_(u'label_start_neutral',
                default=u"Create content initially as neutral language."),
        default=True,
        required=False)


class IMLangOptions(Interface):
    """ Utility to manage the language related options
    """
    supported_langs = List(
            title=_(u"heading_allowed_languages",
                default=u"Allowed languages"),
            description=_(u"description_allowed_languages",
                                  default=u"Select the languages that can be added in "
                                           "your portal."),
            required=True,
            missing_value=list('en'),
            value_type=Choice(
                        vocabulary="plone.app.vocabularies.AvailableContentLanguages"
                        ))
                    
    supported_types = Tuple(
            title=_(u"heading_allowed_types",
                default=u"Allowed types"),
            description=_(u"description_allowed_types",
                                  default=u"Select translatable portal types "),
            required=False,
            missing_value=tuple(),
            value_type=Choice(
                        vocabulary="plone.app.vocabularies.ReallyUserFriendlyTypes"
                        ))

    display_flags = Bool(
        title=_(u'label_display_flags',
                default=u"Display flags for language selection"),
                description=_(u"help_display_flags",
                              default=u"(May be politically sensitive in some "
                                       "areas, do not use this unless you "
                                       "know that it is acceptable)."),
                default=False,
                required=False)



class ILangOptions(IMLangOptions, ILanguageSelectionSchema, IPolicyOptions):
    """ Marker interface union of the language options from pts and multilingual    
    """
   
   
#
# Internal Interfaces
# 

   
class ITranslationUtility(Interface):
    """ Utility to manage the translations
    """

    def addTranslationGroup(object,language):
        """
        add a group on the translation set
        """


class ITranslationGroupLookup(Interface):
    """ Search for a Persistent Translation Group
    """

class ITranslate(Interface):
    """ Marker to translate a object
    """

class ITranslatableElement(Interface):
    """ Marker interface for something that can be translated
    """

class ITranslationService(Interface):
    """ A service where we can ask to translate something
    """

    name = Attribute("Name of the translation Service")

    def getTranslation(fromlanguage, language, element):
        pass

class ITranslatable(Interface, IHasRelations):
    """ Marker interface for translatable content
    """



class ITranslationGroup(Interface):
    """This is a group of translatable
       API of Multilingual on content objects
    """

    uid = Attribute("Unique id identifing the group")

    authorative = Attribute("The authoritative language")

    def addTranslation(language, context=None, origin=None, translatedObject=None, **kwargs):
        """
        Add a new language translation of this content.
        """

    def removeTranslation(language):
        """
        Removes a translation
        """

    def getTranslations():
        """
        Return a dict of {lang : [object, wf_state]} TODO XXX Workflow ?
        """

    def getTranslation(language='language'):
        """
        Return the object corresponding to a translated version or None.
        If called without arguments it returns the translation in the currently
        selected language, or self.
        """

    def getTranslationLanguages():
        """
        Return a list of language codes
        """
        
    def hasTranslation(language):
        """
        Return if object has a translation
        """
        


class ILocateTranslation(Interface):
    context = Attribute("context",
                        "The object that is being translated")

    def findLocationForTranslation(language):
        """Find and return a location for a new translation.

        This may either return an existing location, or create a new folder and
        return that.
        """


class ITranslationFactory(Interface):
    context = Attribute("context",
                        "The object that is being translated")

    def createTranslation(container, language, *args, **kwargs):
        """Create and return a translation.

        The extra arguments are passed to the object creation logic
        and can be used to initialize fields.

        Create a translation of the context for the given language in
        the specicified folder. The new object is returned.

        This method has to setup the translation reference on the
        new object.
        """


class ILanguageIndependentFields(Interface):
    context = Attribute("context", "A translatable object")

    def getFields():
        """Return list of language independent fields"""

    def getFieldsToCopy(translation):
        """Return list of language independent fields to copy to translation.

        The list only includes fields present in both source and destination
        schemas.
        """

    def copyField(field, translation):
        """Copy a language independent field to translation."""

    def copyFields(translation):
        """Copy language independent fields to translation."""



class ILanguageDependentFields(Interface):
    context = Attribute("context", "A translatable object")

    def getFields():
        """Return list of language dependent fields"""

    def getFieldsToCopy(translation):
        """Return list of language dependent fields to copy to translation.

        The list only includes fields present in both source and destination
        schemas.
        """

    def copyField(field, translation):
        """Copy a language dependent field to translation."""

    def copyFields(translation):
        """Copy language dependent fields to translation."""

 	
class IMultilingualLayer(Interface):
 	    """A layer specific for LinguaPlone.

        We will use this to register browser pages that should only be used
        when LinguaPlone is installed in the site.
        """

class ILanguageFolder(INavigationRoot):
    """Marker interface for a root-level language folder"""

class ILanguageURL(IBrowserView):
    """Provide access to the enclosing language folder

    If no language folder can be found, the portal root is used instead.
    
    """
    language_folder = Attribute("The enclosing ILanguageFolder object")
    title = Attribute("The title of the language_folder")
    
    def __call__():
        """The URL of the language folder"""

